package com.snowj.apaas.service.utils;

import com.google.common.collect.Lists;
import com.snowj.apaas.domain.auto.*;
import com.snowj.apaas.service.TrademarkService;
import com.snowj.apaas.web.*;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.*;

import java.beans.PropertyDescriptor;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.Arrays;

public class TypescriptModelUtil {

    /**
     * 根据 java 类生产 typescript 代码
     * @param tClass 需要生成类
     * @param <T> 需要生成的类类型
     */
    public static <T> void generateDomains(Class<T> tClass) {
        PropertyDescriptor[] propertyDescriptors = BeanUtils.getPropertyDescriptors(tClass);
        System.out.println(String.format("export default class %s {", tClass.getSimpleName()));
        System.out.println("\tconstructor (");
        for (PropertyDescriptor descriptor : propertyDescriptors) {
            if (!descriptor.getName().equals("class")) {
                Class<?> typeClass = descriptor.getPropertyType();
                String type = typeClass.getSimpleName();
                if (type.equals("String") || type.equals("Date")) type = "string";
                if (type.equals("Long") || type.equals("Integer") || type.equals("Double") || type.equals("Float"))
                    type = "number";
                if (type.equals("Boolean")) type = "boolean";
                System.out.println(String.format("\t\tpublic %s?: %s,", descriptor.getName(), type));
            }
        }
        System.out.println("\t) {");
        for (PropertyDescriptor descriptor : propertyDescriptors) {
            if (!descriptor.getName().equals("class")) {
                System.out.println(String.format("\t\tthis.%s = %s ? %s : undefined;", descriptor.getName(), descriptor.getName(), descriptor.getName()));
            }
        }
        System.out.println("\t}");
        System.out.println("}");
    }

    public static <T> void generateMethods(Class<T> tClass, String typename) {
        Method[] methods = tClass.getMethods();
        System.out.println("import {request} from 'umi';");
        System.out.println(String.format("import type %s from '@/domain/%s';", typename, typename));
        System.out.println();
        System.out.println();
        for (Method method: methods) {
            if (!Lists.newArrayList("wait", "equals", "toString", "hashCode", "getClass", "notify", "notifyAll").contains(method.getName())) {
                Annotation[] annotations = method.getDeclaredAnnotations();
                String methodType = "get";
                String url = "/";
                String params = "data";
                String  typeInfo = typename;
                for (Annotation annotation : annotations) {
                    if (annotation instanceof GetMapping) {
                        String[] value = ((GetMapping) annotation).value();
                        url = value[0];
                        params = "params";
                        methodType = "get";
                    } else if (annotation instanceof PostMapping) {
                        String[] value = ((PostMapping) annotation).value();
                        url = value[0];
                        methodType = "post";
                    } else if (annotation instanceof PutMapping) {
                        String[] value = ((PutMapping) annotation).value();
                        url = value[0];
                        methodType = "put";
                    } else if (annotation instanceof DeleteMapping) {
                        String[] value = ((DeleteMapping) annotation).value();
                        url = value[0];
                        methodType = "delete";
                        typeInfo = "void";
                    } else if (annotation instanceof PatchMapping) {
                        String[] value = ((PatchMapping) annotation).value();
                        url = value[0];
                        methodType = "patch";
                    }
                }
                String methodName = method.getName();

                System.out.println(String.format("export async function %s(data?: any) {", methodName));
                System.out.println(String.format("        return request<%s>(`/api%s`, {", typeInfo, url));
                System.out.println(String.format("        method: '%s',", methodType));
                System.out.println(String.format("        %s: data", params));
                System.out.println(String.format("    });"));
                System.out.println("}");
                System.out.println();
            }
//            Parameter[] parameters = method.getParameters();
//            for (Parameter parameter : parameters) {
//                System.out.println(parameter.getName() + ", " + parameter.getType().getSimpleName());
//            }
        }
    }

    public static void main(String[] args) {
        TypescriptModelUtil.generateMethods(UserGroupsController.class, "UserGroups");
    }
}
